#ifndef PROTOCOL_H
#define PROTOCOL_H
/*
 * The main communication between client-server-client should be through
 * bitwise encoded ints. Commands sohuld be odd and movements should be
 * even.  Since clients cannot communicate directly the server sends
 * client commands and the client sends sever commands (this should make
 * more sence later).  This is just an idea for some defined variables
 * to handle this.
 *
 * The server should keep track of moves made in the game, so that if a
 * spectator joins in there game will have the correct display.
 */

/* So that sizeof() is more descriptive */
#define CODE int

/* Get bit n of an integral (starting at zero) */
#define BIT(n) (1<<(n))

/*
 * The reason for this is so we can quickly check to see if we can just
 * pass on the movement to the client. After a move, the client will
 * send the room that the move goes with.
 */
#define COMMAND    BIT(0)
#define X          BIT(1)
#define O          BIT(2)
#define UPPERLEFT  BIT(3)
#define UPPER      BIT(4)
#define UPPERRIGHT BIT(5)
#define LEFT       BIT(6)
#define CENTER     BIT(7)
#define RIGHT      BIT(8)
#define LOWERLEFT  BIT(9)
#define LOWER      BIT(10)
#define LOWERRIGHT BIT(11)

/*
 * If you logical OR all the moves from one player together and then
 * logical AND that value with one of these values and get a true, that
 * player is the winner.
 */
/* Winning codes */
#define WINNING_BYTE_CODE_1 (UPPERLEFT  | UPPER  | UPPERRIGHT)
#define WINNING_BYTE_CODE_2 (LEFT       | CENTER | RIGHT     )
#define WINNING_BYTE_CODE_3 (LOWERLEFT  | LOWER  | LOWERRIGHT)
#define WINNING_BYTE_CODE_4 (UPPERLEFT  | LEFT   | LOWERLEFT )
#define WINNING_BYTE_CODE_5 (UPPER      | CENTER | LOWER     )
#define WINNING_BYTE_CODE_6 (UPPERRIGHT | RIGHT  | LOWERRIGHT)
#define WINNING_BYTE_CODE_7 (UPPERLEFT  | CENTER | LOWERRIGHT)
#define WINNING_BYTE_CODE_8 (UPPERRIGHT | CENTER | LOWERLEFT )
/*
 * Server: Sends all in room winners ID. Server has decieded a winner
 * and has been stated.
 */
#define WINNER 3
#define CATSGAME 0

/*
 * Some request need confirmation before the client continues to send
 * data to the server, this includes JOIN and PLAYERS.
 */
#define KICK 1
#define ACCEPTED 5
#define DENIED 7
#define ADMIN 9
#define SERVERFULL 11

/*
 * Client: Send integer of name length, then sends the name.
 */
#define USERNAME 13

/*
 * Client: Sends the room number they wish to join.
 * Server: Sends back ACCEPTED and then sends all players in the room;
 * JOIN, room ID, and Player ID.
 */
#define JOIN 15
/*
 * Client: Sends the room number they wish to leave.
 * Server: Sends all players in the room; JOIN, room ID, and Player ID.
 */
#define LEAVE 17

/*
 * The Client will manage their own players and the rooms.
 */
/* Server: Sends all of the player's information.
 *  	ID
 * 	Length of name.
 *  	name
 *  	gamesPlayed
 *		wins
 *		losses
 */
#define PLAYER 19
/* Server: Sends all of the room information.
 *		ID
 *		Length of name
 *		name
 *		gamesPlayed
 *		numberInRoom
 *		player1
 *		player2 ...
 *		maxForRoom
 *		playerX, playerO
 *		admin
 *		moves
 */
#define ROOM 21
/* Request for all connected players and rooms */
#define REFRESH 23
/*
 * Client: Sends room ID and 2 player ID's. This is the players for the
 * game, the server will decied who is X and who O.
 */
#define PLAYERS 25


/*
 * Client should only need to send position clicked, server will attach
 * if the move was done by player X or player O.
 */

#define TIES(player) ((player)->gamesPlayed - (player)->wins - (player)->losses)

#define MOVES_IN_A_GAME 9

typedef struct Player {
	char* name;
	int ID;
	int gamesPlayed;
	int wins;
	int losses;
} Player;

#define NEXT(rm, plid) \
	(((plid) == (rm)->playerX) ? ((rm)->playerO) : ((rm)->playerX))
typedef struct Room {
	char* name;
	int ID;
	int gamesPlayed;
	int numberInRoom;
	int maxForRoom;
	int playerX;
	int playerO;
	int nextPlayer;
	int admin;
	int* players;
	int moves[MOVES_IN_A_GAME];
} Room;

#endif
